import { useMutation, useQueryClient } from '@tanstack/react-query';
import { Form, Input, message, Modal, Select } from 'antd';
import React from 'react';

import api from '@/apis/api';
import localINFO from '@/utils/localInfo';

interface AddIpAddressProps {
  title: string;
  visible: boolean;
  setVisible: (visible: boolean) => void;
}

const AddIpAddress: React.FC<AddIpAddressProps> = ({ title, visible, setVisible }) => {
  const [form] = Form.useForm();
  const { Option } = Select;
  const queryClient = useQueryClient();

  const AddWhiteList = useMutation({
    mutationFn: (params: any) => api.AddWhiteList(params),
    onSuccess: (res: any) => {
      if (res?.success) {
        message.success('添加成功');
      } else {
        message.error(`添加失败,${res?.message}`);
      }
    },
    onError: () => {
      message.error('添加失败');
    },
    onSettled: () => queryClient.invalidateQueries({ queryKey: ['getWhiteListData'] }),
    mutationKey: ['getWhiteListData'],
  });

  // 黑名单
  const AddBlackList = useMutation({
    mutationFn: (params: any) => api.AddBlackList(params),
    onSuccess: (res: any) => {
      if (res?.success) {
        message.success({ content: '添加成功！', key: 'addLoading', duration: 1 });
      } else {
        message.success({
          content: `添加失败, ${res?.message}`,
          key: 'addLoading',
          duration: 1,
        });
      }
    },
    onError: () => {
      message.error('添加失败');
    },
    onSettled: () => queryClient.invalidateQueries({ queryKey: ['getBlackListData'] }),
    mutationKey: ['getBlackListData'],
  });

  const handleaddOk = async () => {
    await form.validateFields();
    const data: FieldType = form.getFieldsValue();
    if (title === '黑名单') {
      AddBlackList.mutate({
        ip: data.ipAddress,
        remark: data.remark,
        port: data.type,
      });
    } else {
      AddWhiteList.mutate({
        ip: data.ipAddress,
        remark: data.remark,
        port: data.type,
      });
    }
    message.loading({ content: '添加中...请稍候', key: 'addLoading' });
    form.resetFields();
    setVisible(false);
  };

  const handleaddCancel = () => {
    form.resetFields();
    setVisible(false);
  };

  type FieldType = {
    ipAddress?: string;
    remark?: string;
    type?: string;
  };

  return (
    <>
      <Modal
        title={`添加${title}`}
        open={visible}
        onOk={handleaddOk}
        onCancel={handleaddCancel}
        cancelText="取消"
        okText="确定"
        destroyOnClose
        okButtonProps={{ disabled: localINFO.getRoleId() !== 1 }}
      >
        <p style={{ marginLeft: 24, color: 'red' }}>
          注意：添加或删除白名单时，请保证至少有一条管理端可用IP！
        </p>
        <Form
          form={form}
          preserve={false}
          name="basic"
          labelCol={{ span: 4 }}
          wrapperCol={{ span: 20 }}
          autoComplete="off"
          style={{ marginTop: 24 }}
        >
          <Form.Item<FieldType>
            label="IP地址"
            name="ipAddress"
            rules={[
              { required: true, message: '请输入IP地址！' },
              {
                pattern: /^(?:(?:\d{1,3}\.){3}\d{1,3})(?:\/(?:8|16|24))?$/,
                message: '请输入有效的IP地址或IP段，例如127.0.0.1或127.0.0.1/24',
              },
            ]}
          >
            <Input.TextArea
              autoComplete="new-address"
              maxLength={500}
              rows={4}
              placeholder="支持特定IP地址，也可以设置IP段进行区间限制，例如 127.0.0.1/24，其中 24 表示采用子网掩码中的前 24 位为有效位。"
            />
          </Form.Item>

          <Form.Item<FieldType>
            label="端口"
            name="type"
            rules={[{ required: true, message: '请选择作用的端口类型！' }]}
          >
            <Select placeholder="请选择作用的端口类型" allowClear>
              <Option value={0}>管理服务</Option>
              <Option value={1}>算法服务</Option>
            </Select>
          </Form.Item>

          <Form.Item<FieldType> label="备注" name="remark">
            <Input maxLength={50} placeholder="请输入备注，50个字符以内" />
          </Form.Item>
        </Form>
      </Modal>
    </>
  );
};

export default AddIpAddress;
